package oop

import "fmt"

// 工厂模式的特点：
// 	1.提供一个函数实例化结构体指针类型的对象。
// 	2.为为结构体提供getter和setter方法(注意:方法有指针接收器)

// 定义结构体。且当前结构体不允许挎包调用。
type clazz struct { // 注意:此时结构体的名字的首字母是小写，所以不能跨包调用
	id     string // 注意:如果属性首字母是大写时，就不需要封装对应的getter和setter方法了。
	name   string
	Number int
}

/*
通过factory实例化一个对象：(这个对象不能被跨包调用)
  - 结构体的名字首字母是小写，是不能跨包调用的。
  - 如果想要初始化，则需要根据我们定义的NewInstance函数来进行实例化。
  - 类似于JAVA中的单例模式。
*/
func NewInstance(varId string, varName string, varNumber int) *clazz { // *clazz是指针类型, &clazz获取变量的内存地址
	var clazz = &clazz{
		id:     varId,
		name:   varName,
		Number: varNumber,
	}
	fmt.Printf("NewInstance函数中，类型:%T,值是:%v\n", clazz, clazz)
	// 打印结果：NewInstance函数中，类型:*oop.clazz,值是:&{202501 软件工程}
	// 注意：返回值是一个指针类型
	return clazz
}

// 为结构体定义getter和setter方法
func (cla *clazz) GetId() string {
	return cla.id
}

func (cla *clazz) SetId(id string) *clazz {
	cla.id = id
	return cla
}

func (cla *clazz) GetName() string {
	return cla.name
}

func (cla *clazz) SetName(name string) *clazz {
	cla.name = name
	return cla
}

// 为结构体定义方法(方法的特点是包含一个指针类型接收器)
func (cla *clazz) PrintInfo() {
	fmt.Printf("clazz(id = %s, name = %s, Number = %d)\n", cla.id, cla.name, cla.Number)
}
